# -*- coding: utf8 -*-

import traceback
from time import sleep
import os
import mimetypes
import magic
from Queue import Queue
import types

from worker import Worker
from images import load_image
from images.vector import process_image
from project.constants import *

class ImageWorker( Worker ):

    queue = None

    mage = None

    number = 0

    p = None

    def get_mime_type( self, mo, full_path ):
        mime = None
        try:
            mime = mo.from_file( full_path )
        except:
            pass
        if not mime:
            mime = mimetypes.guess_type( full_path )[0]
        if not mime:
            mime = "application/octet-stream"
        return mime


    def run_image(self, file_id, tmp_dir, image_path):

        sess = self.p.get_session()

        self.app.get_stats().inc("images_count", 1)

        try:
            fsize = os.path.getsize( image_path )
            mime = self.get_mime_type( self.mage, image_path )

            res = load_image(image_path)

            im = res["image"]
            w = res["width"]
            h = res["height"]
            mode = res["mode"]

            self.app.get_stats().inc("images_size", fsize )

            res = process_image(im, parts=10)

            anim = False
            try:
                im.seek(1)
                anim = True
            except EOFError:
                pass

            name = image_path.replace(tmp_dir, "")

            img_item = self.p.insert_image(
                file_id, name, anim, mime, fsize, res["color"] == False ,
                w, h, mode, res["mean_gray"]
            )

            v10_item = self.p.insert_image_v10(
                img_item.id, IMAGE_VECTOR_ORIENTATION_NORMAL ,
                *res["vector"]
            )
            sess.expunge( v10_item )

            res = load_image(image_path)
            im = res["image"]

            res = process_image(im, mirror=True, parts=10)

            v10_item = self.p.insert_image_v10(
                img_item.id, IMAGE_VECTOR_ORIENTATION_FLIP_LEFT_RIGHT ,
                *res["vector"]
            )
            sess.expunge( v10_item )


            res = process_image(im)

            v100_item = self.p.insert_image_v100(
                img_item.id, IMAGE_VECTOR_ORIENTATION_NORMAL ,
                ",".join([ str(v) for v in res["vector"] ])
            )
            sess.expunge( v100_item )

            res = process_image(im, mirror=True)

            v100_item = self.p.insert_image_v100(
                img_item.id, IMAGE_VECTOR_ORIENTATION_FLIP_LEFT_RIGHT ,
                ",".join([ str(v) for v in res["vector"] ])
            )
            sess.expunge( v100_item )


            sess.expunge( img_item )

            self.app.get_stats().inc("images_processed", 1)

        except Exception, e:
            self.app.get_stats().inc("errors_count", 1)
            print("ImageWorker[%s]:\nFile=%r\n ERROR!\n%s" % ( self.number, image_path, traceback.format_exc() ) )
            pass
        return

    def run ( self ):
        
        # print("ImageWorker[%s]: START" % self.number)

        mimetypes.init()

        self.mage = magic.open( magic.MAGIC_MIME_TYPE )
        self.mage.load()

        self.p = self.app.get_project()

        while not self.stop_event.isSet():

            try:
                data = self.queue.get_nowait()
            except:
                data = None

            if data is None:
                sleep(0.01)
                continue

            if type(data) in types.StringTypes:
                if data == "quit":
                    self.stop_event.set()
            elif type(data) in ( types.ListType, types.TupleType, ):

                file_id, image_path, tmp_dir = data

                self.run_image(file_id, tmp_dir, image_path )

                self.app.get_stats().inc_imaging(1)

            self.queue.task_done()
        
        # print("ImageWorker[%s]: STOP" % self.number)

        self.p.close_session()
        self.p = None

        self.stop_event.clear()
        return


class ImageTaskManager(object):

    _queue = None
    _workers = None

    # cput = cpu_count()
    cpu = 1

    def __init__(self):
        self._queue = Queue()
        pass

    def add_task(self, data):
        self._queue.put_nowait(data)
        return self

    def run(self, app):
        self._workers = []

        for i in range(self.cpu):

            self.add_task("quit")

            th = ImageWorker(app)
            th.queue = self._queue
            th.number = i
            th.start()

            self._workers.append(th)

    def check(self):
        done = True

        for i in range(self.cpu):
            th = self._workers[i]
            if th and th.is_alive():
                done = False

        return done

    def stop(self):
        for i in range(self.cpu):
            th = self._workers[i]
            th.stop_event.set()
        return self

    def wait(self):
        done = False
        while not done:
            done = True

            for i in range(self.cpu):
                th = self._workers[i]
                if th and th.is_alive():
                    done = False

            sleep(0.01)

